from PySide6.QtWidgets import QWidget, QFormLayout, QLineEdit, QLabel, QPushButton, QComboBox, QMessageBox
from PySide6.QtCore import QTimer
from PySide6.QtGui import QPixmap
import base64

class LoginTab(QWidget):
    def __init__(self):
        super().__init__()
        self.status_timer = None  # 初始化状态轮询定时器
        layout = QFormLayout()
        
        # 用户名密码输入
        self.user_edit = QLineEdit()
        self.pass_edit = QLineEdit(echoMode=QLineEdit.Password)
        
        # 验证码区域
        self.captcha_label = QLabel()
        self.captcha_btn = QPushButton("刷新验证码")
        self.captcha_input = QLineEdit()
        
        # 登录方式选择
        self.login_method = QComboBox()
        self.login_method.addItems(["密码登录", "二维码登录"])
        self.login_method.currentIndexChanged.connect(self.on_login_method_changed)

        # 二维码显示区域
        self.qrcode_label = QLabel()
        self.qrcode_label.setHidden(True)
        self.refresh_qrcode_btn = QPushButton("刷新二维码")
        self.refresh_qrcode_btn.setHidden(True)
        self.refresh_qrcode_btn.clicked.connect(self.request_qrcode)

        # 登录按钮
        login_btn = QPushButton("登录")
        login_btn.clicked.connect(self.start_login)

        # 布局组合
        layout.addRow("登录方式:", self.login_method)
        layout.addRow("用户名:", self.user_edit)
        layout.addRow("密码:", self.pass_edit)
        layout.addRow("验证码:", self.captcha_input)
        layout.addRow(self.captcha_label)
        layout.addRow(self.captcha_btn)
        layout.addRow(self.qrcode_label)
        layout.addRow(self.refresh_qrcode_btn)
        layout.addRow(login_btn)
        # 登录状态显示
        self.status_label = QLabel("未登录")
        self.status_label.setStyleSheet("color: red; font-weight: bold;")
        layout.addRow("当前状态:", self.status_label)
        # 退出按钮（初始隐藏）
        self.logout_btn = QPushButton("退出登录")
        self.logout_btn.setHidden(True)
        self.logout_btn.clicked.connect(self.logout)
        layout.addRow(self.logout_btn)
        
        self.setLayout(layout)
        
    def update_captcha(self, pixmap):
        """更新验证码图像"""
        self.captcha_label.setPixmap(pixmap)

    def handle_login_response(self, result):
        """处理登录响应结果"""
        self.login_btn.setEnabled(True)
        if result['success']:
            # 登录成功，更新状态显示
            self.status_label.setText("登录成功")
            self.status_label.setStyleSheet("color: green; font-weight: bold;")
            self.logout_btn.setHidden(False)  # 显示退出按钮
            # 切换到查询页面
            main_window = self.window()
            main_window.tabs.setCurrentWidget(main_window.query_page)
            QMessageBox.information(self, "成功", "登录成功！")
        else:
            # 登录失败，显示错误信息
            QMessageBox.critical(self, "失败", f"登录失败：{result['message']}")
            # 刷新验证码
            self.worker.get_captcha()  # 假设后台线程有获取验证码的方法
    
    def start_login(self):
        """启动登录流程"""
        if self.login_method.currentText() == "密码登录":
            # 输入验证
            username = self.user_edit.text().strip()
            password = self.pass_edit.text().strip()
            captcha = self.captcha_input.text().strip()
            
            if not username:
                QMessageBox.warning(self, "错误", "请输入用户名")
                return
            if not password:
                QMessageBox.warning(self, "错误", "请输入密码")
                return
            if not captcha:
                QMessageBox.warning(self, "错误", "请输入验证码")
                return
            
            # 异步登录请求（使用后台线程）
            self.login_btn.setEnabled(False)
            self.worker = self.window().worker  # 获取主窗口的后台线程
            self.worker.login_signal.connect(self.handle_login_response)
            self.worker.cookie_invalid_signal.connect(self.on_cookie_invalid)
            self.worker.start_login(username, password, captcha)
        else:
            # 二维码登录直接请求二维码
            self.request_qrcode()

    def on_login_method_changed(self, index):
        """登录方式切换事件处理"""
        is_qrcode = self.login_method.currentText() == "二维码登录"
        # 切换输入框可见性
        self.user_edit.setHidden(is_qrcode)
        self.pass_edit.setHidden(is_qrcode)
        self.captcha_input.setHidden(is_qrcode)
        self.captcha_label.setHidden(is_qrcode)
        self.captcha_btn.setHidden(is_qrcode)
        # 切换二维码区域可见性
        self.qrcode_label.setHidden(not is_qrcode)
        self.refresh_qrcode_btn.setHidden(not is_qrcode)
        # 切换为二维码登录时自动刷新
        if is_qrcode:
            self.request_qrcode()

    def request_qrcode(self):
        """请求二维码数据并启动状态轮询"""
        self.worker = self.window().worker
        self.worker.qrcode_signal.connect(self.handle_qrcode_result)
        print(f'[DEBUG] 已成功连接qrcode_signal到handle_qrcode_result')  # 新增信号连接日志
        self.worker.qrcode_status_signal.connect(self.handle_qrcode_status)
        # 停止之前的定时器（如果存在）
        if self.status_timer is not None and self.status_timer.isActive():
            self.status_timer.stop()
        # 初始化轮询定时器（每2秒检查一次状态）
        self.status_timer = QTimer(self)
        self.status_timer.setInterval(2000)
        self.status_timer.timeout.connect(self.check_qrcode_status)
        self.worker.get_qrcode()

    def handle_qrcode_result(self, qrcode_data):
        """处理二维码返回结果（包含uuid和图片）"""
        print(f'[DEBUG] 接收到二维码信号，数据是否为空: {qrcode_data is None}')  # 新增信号接收日志
        print(f'[DEBUG] 二维码数据详情 - uuid: {qrcode_data.get("uuid", "无uuid")}, image前50字符: {qrcode_data.get("image", "")[:50]}')  # 新增详细数据日志
        if not qrcode_data:
            QMessageBox.critical(self, "错误", "获取二维码失败，请重试")
            return
        # 检查数据结构是否包含必要字段
        if 'image' not in qrcode_data or 'uuid' not in qrcode_data:
            QMessageBox.critical(self, "错误", "二维码数据结构不完整，缺少必要字段")
            print(f'[ERROR] 二维码数据结构异常，实际字段: {qrcode_data.keys()}')  # 新增结构检查日志
            return
        # 显示二维码图片
        pixmap = QPixmap()
        try:
            image_data = base64.b64decode(qrcode_data['image'])
            print(f'[DEBUG] 二维码Base64解码后数据长度: {len(image_data)}字节')  # 新增解码后数据长度日志
        except (base64.binascii.Error, TypeError) as e:
            QMessageBox.critical(self, "错误", f"二维码图片解码失败（无效Base64）: {str(e)}")
            print(f'[ERROR] 二维码Base64解码失败: {str(e)}，原始数据长度: {len(qrcode_data.get("image", ""))}字节')  # 新增错误细节日志
            return
        # 加载图片并检查是否成功
        load_success = pixmap.loadFromData(image_data)
        if not load_success:
            QMessageBox.critical(self, "错误", "二维码图片数据无效，无法加载（可能格式不支持）")
            print(f'[ERROR] QPixmap加载失败，数据长度: {len(image_data)}字节，推测格式: {self._guess_image_format(image_data[:16])}')  # 新增加载失败详细日志
            return
        self.qrcode_label.setPixmap(pixmap.scaled(200, 200))
        # 记录二维码显示日志
        print(f'[DEBUG] 二维码图片已成功加载，尺寸: {pixmap.width()}x{pixmap.height()}，格式: {self._guess_image_format(image_data[:16])}')  # 修正格式获取方式（基于文件头推测）
        # 保存uuid并启动状态轮询
        self.current_uuid = qrcode_data['uuid']
        self.status_timer.start()

    def _guess_image_format(self, header):
        """根据文件头推测图片格式"""
        formats = {
            b'\x89PNG\r\n\x1a\n': 'PNG',
            b'\xff\xd8\xff': 'JPEG',
            b'GIF87a': 'GIF',
            b'GIF89a': 'GIF',
            b'\x42\x4d': 'BMP'
        }
        for sig, fmt in formats.items():
            if header.startswith(sig):
                return fmt
        return '未知格式'

    def _pixmap_format_to_str(self, format_enum):
        """将QPixmap格式枚举转换为字符串"""
        format_map = {
            QPixmap.Format_ARGB32: 'ARGB32',
            QPixmap.Format_RGB32: 'RGB32',
            QPixmap.Format_ARGB32_Premultiplied: 'ARGB32预乘',
            QPixmap.Format_RGB16: 'RGB16',
            QPixmap.Format_RGB888: 'RGB888',
            QPixmap.Format_RGB444: 'RGB444',
            QPixmap.Format_RGB555: 'RGB555',
            QPixmap.Format_ARGB8555_Premultiplied: 'ARGB8555预乘',
            QPixmap.Format_ARGB6666_Premultiplied: 'ARGB6666预乘',
            QPixmap.Format_ARGB8888: 'ARGB8888',
            QPixmap.Format_ARGB8888_Premultiplied: 'ARGB8888预乘',
            QPixmap.Format_RGBX8888: 'RGBX8888',
            QPixmap.Format_RGBA8888: 'RGBA8888',
            QPixmap.Format_RGBA8888_Premultiplied: 'RGBA8888预乘'
        }
        return format_map.get(format_enum, '未知格式')

    def check_qrcode_status(self):
        """触发后台线程检查二维码状态"""
        if hasattr(self, 'current_uuid'):
            self.worker.check_qrcode_status(self.current_uuid)

    def handle_qrcode_status(self, status_info):
        if status_info.get('status') == 'success':
            # 二维码登录成功，更新状态显示
            self.status_label.setText("登录成功")
            self.status_label.setStyleSheet("color: green; font-weight: bold;")
            self.logout_btn.setHidden(False)  # 显示退出按钮

    def logout(self):
        """处理退出登录逻辑"""
        # 清除cookie缓存
        self.worker.user_cookies = None
        # 停止cookie校验定时器
        if hasattr(self.worker, 'cookie_check_timer'):
            self.worker.cookie_check_timer.stop()
        # 更新状态显示
        self.status_label.setText("未登录")
        self.status_label.setStyleSheet("color: red; font-weight: bold;")
        self.logout_btn.setHidden(True)  # 隐藏退出按钮
        # 切换回登录页面（假设主窗口有tabs属性）
        main_window = self.window()
        main_window.tabs.setCurrentWidget(main_window.login_page)

    def on_cookie_invalid(self):
        """处理cookie无效事件"""
        QMessageBox.warning(self, "提示", "登录状态已过期，请重新登录")
        self.logout()
        """处理二维码状态变化"""
        if status_info['status'] == 'success':
            self.status_timer.stop()
            QMessageBox.information(self, "成功", status_info['message'])
            # 登录成功，切换到查询页面
            main_window = self.window()
            main_window.tabs.setCurrentWidget(main_window.query_page)
        elif status_info['status'] == 'scanned':
            QMessageBox.information(self, "提示", status_info['message'])
        elif status_info['status'] == 'error':
            self.status_timer.stop()
            QMessageBox.critical(self, "错误", status_info['message'])